package com.dragon.backstage.advice;

import com.dragon.backstage.domain.vo.BasicVo;
import com.dragon.backstage.service.UserService;
import com.dragon.common.constant.BasicConstant;
import com.dragon.common.domain.vo.PaginationVo;
import com.dragon.common.utils.AjaxResult;
import com.dragon.common.utils.MdcUtils;
import com.dragon.common.utils.ServletUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * 全局统一响应体处理
 *
 * @author dragon
 * @version 1.0
 * @date 2024/8/5 18:27
 */
@Slf4j
@RestControllerAdvice
public class AjaxResultResponseBodyAdvice implements ResponseBodyAdvice<AjaxResult<?>> {

    @Resource
    private UserService userService;


    @Override
    public boolean supports(@NonNull MethodParameter returnType, @NonNull Class<? extends HttpMessageConverter<?>> converterType) {
        return returnType.getGenericParameterType().getTypeName().contains(AjaxResult.class.getName());
    }

    @Override
    public AjaxResult<?> beforeBodyWrite(AjaxResult<?> body, @NonNull MethodParameter returnType, @NonNull MediaType selectedContentType, @NonNull Class<? extends HttpMessageConverter<?>> selectedConverterType, @NonNull ServerHttpRequest request, @NonNull ServerHttpResponse response) {
        if (body != null) {
            // 全局追踪ID
            String traceId = MdcUtils.get(BasicConstant.TRACE_ID);
            body.setTraceId(traceId);

            Object data = body.getData();

            // 分页
            if (data instanceof PaginationVo<?> paginationVo) {
                // 获取页数
                Integer pageNum = ServletUtils.getParameterToInt("pageNum", 1);
                // 获取条数
                Integer pageSize = ServletUtils.getParameterToInt("pageSize", 10);

                paginationVo.setPageNum(pageNum);
                paginationVo.setPageSize(pageSize);

                if (paginationVo.getRows() != null) {
                    paginationVo.getRows().forEach(this::processItem);
                }
            } else {
                if (data instanceof Iterable) {
                    ((Iterable<?>) data).forEach(this::processItem);
                } else {
                    processItem(data);
                }
            }
        }

        return body;
    }

    /**
     * 补全创建者/更新者的昵称
     */
    private void processItem(Object item) {
        if (item instanceof BasicVo basicVo) {
            String createBy = basicVo.getCreateBy();
            String updateBy = basicVo.getUpdateBy();

            if (StringUtils.isNotBlank(createBy)) {
                String createByName = userService.getNickNameByAccount(createBy);
                basicVo.setCreateByName(createByName);
            }

            if (StringUtils.isNotBlank(updateBy)) {
                String updateByName = userService.getNickNameByAccount(updateBy);
                basicVo.setUpdateByName(updateByName);
            }
        }
    }

}
